home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gigarom 1
/
Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso
/
FILES
/
BBS
/
MUBBS
/
MUBBS etc.cpt
/
Module Source
/
Serial Module code
/
serial module.c
< prev
next >
Wrap
Text File
|
1991-11-21
|
13KB
|
472 lines
/*
* Serial Module.c
*
* This program source code and it's compiled version is
* Copyright (c) 1991 N. Hawthorn.
* This program source code and it's compiled version IS NOT IN THE
* PUBLIC DOMAIN ! Please read the "COPYRIGHT NOTICE / NH" file for details
* regarding use of this program source code and it's compiled version.
*
* This module's name is "serial", it's type is "MOD1", usea resource mover
* to assign a new number to it, that's why we name our modules !
*
* THIS IS A INIT MODULE, IT NEEDS TO BE IN LISTED IN THE "INITMODULES" LIST
* It only needs to be called as a INIT, it just sets up the serial I/O pointers
*
* Notice that we use "Hook Stuff.h" and we do not just "return", but jump to
* "end" and there set the A4 register before returning.
*
*/
#define INMAIN
#include <SetUpA4.h>
#include "MUBBS Module.h"
#include "Hook Stuff.h"
#include <SerialDvr.h>
#include <DeviceMgr.h>
#include <FileMgr.h>
/*
#define AinRefNum (-6) ; just for info
#define AoutRefNum (-7)
#define BinRefNum (-8)
#define BoutRefNum (-9)
*/
#define SWITCHNOW 5 /* max times of not switching before a force switch */
/* my globals for this module */
static char inbuffA[1024], /* the serial read buffer locked down */
inbuffB[1024]; /* the serial read buffer locked down */
pascal void main (mode1,G1,P1)
int mode1;
struct GS *G1;
Ptr P1; /* we ignore "P" in this module */
{
Handle temph;
float version = 0.5; /* what version of MUBBS you are compatable with IE: .5 and above */
RememberA0(); SetUpA4(); /* This sets up the A4 register to access our globals */
asm { _RecoverHandle }; asm {move.l a0,temph}; HLock(temph); /* locks our module, do this ! */
G=G1; /* This MUST be the first thing you do in main only, it sets up the struct globals */
mode[u]=mode1; /* set up our mode so that you can read it anywhere */
storeA4(); /* save the value of A4 for later calls, only in this type of SPECIAL module */
switch (mode[u]) { /* any un-handled modes return error from this module */
case 98: /* NOTE that this DOESN'T unlock */
versionck(version); /* just return after this call, don't modify anything */
goto skip1; /* DON'T UNLOCK */
break;
case 0:
strcpy (G->programmer,"N Hawthorn"); /* show the programmer's name up to 20 chars*/
setpointers(); /* init call, set up the pointers now */
G->moduleresult=99; /* we put 99 here because we need to be called to CLOSE */
goto skip1; /* DON'T UNLOCK */
break;
case 1:
G->moduleresult=0; /* bye bye call, UNLOCK NOW */
break;
default:
G->moduleresult=1; /* return bad code */
};
HUnlock(temph); /* unlocks this module, do this ! */
skip1:
RestoreA4(); /* call this when you are all done */
}
sOpen1 () {
static SerShk *handshake;
int serConfig, serBlen;
int err;
getA4();
if (u == G->localuser || u > 1) goto end; /* don't open if it's the local user */
if (u==0) {
if (err = RAMSDOpen(sPortA)) {
print("\nC> ERROR ! Cannot open the serial driver A\n");
}
print("<serial driver A opened> ");
serConfig=data8+stop10+noParity;
if (strcmp(G->userbaud[u],"300") == 0) serConfig=serConfig+baud300;
if (strcmp(G->userbaud[u],"1200") == 0) serConfig=serConfig+baud1200;
if (strcmp(G->userbaud[u],"2400") == 0) serConfig=serConfig+baud2400;
if (strcmp(G->userbaud[u],"9600") == 0) serConfig=serConfig+baud9600;
if (strcmp(G->userbaud[u],"19200") == 0) serConfig=serConfig+baud19200;
if (err = SerReset(AinRefNum, serConfig)) print("\n ERROR ! calling serial config A\n");
handshake->fXOn = 0; /* no XON/XOFF output flow control */
handshake->fCTS = 0; /* no CTS (input) hardware handshake */
handshake->xOn = 0x00; /* XON character */
handshake->xOff = 0x00; /* XOFF character */
handshake->errs = 0; /* Ignore input errors */
handshake->evts = 0; /* No device driver events */
handshake->fInX = 0; /* no XON/XOFF input flow control */
handshake->fDTR = 0; /* no DTR (output) hardware handshake */
if (err = SerHShake(AinRefNum, handshake)) print("\nERROR ! calling serialHShake A\n");
serBlen = 2048; /* set the buffer length */
if (err = SerSetBuf(AinRefNum, &inbuffA, serBlen)) print("\nERROR ! setting up serial buffer A\n");
print("<serial port A configed >\n");
}
if (u==1) {
if (err = RAMSDOpen(sPortB)) {
print("\nERROR ! Cannot open the serial driver B\n");
}
print("<serial driver B opened> ");
serConfig=data8+stop10+noParity;
if (strcmp(G->userbaud[u],"300") == 0) serConfig=serConfig+baud300;
if (strcmp(G->userbaud[u],"1200") == 0) serConfig=serConfig+baud1200;
if (strcmp(G->userbaud[u],"2400") == 0) serConfig=serConfig+baud2400;
if (strcmp(G->userbaud[u],"9600") == 0) serConfig=serConfig+baud9600;
if (strcmp(G->userbaud[u],"19200") == 0) serConfig=serConfig+baud19200;
if (err = SerReset(BinRefNum, serConfig)) print("\nERROR ! calling serial config B\n");
handshake->fXOn = 0; /* no XON/XOFF output flow control */
handshake->fCTS = 0; /* no CTS (input) hardware handshake */
handshake->xOn = 0x00; /* XON character */
handshake->xOff = 0x00; /* XOFF character */
handshake->errs = 0; /* Ignore input errors */
handshake->evts = 0; /* No device driver events */
handshake->fInX = 0; /* no XON/XOFF input flow control */
handshake->fDTR = 0; /* no DTR (output) hardware handshake */
if (err = SerHShake(BinRefNum, handshake)) print("\nERROR ! calling serialHShake B\n");
serBlen = 2048; /* set the buffer length */
if (err = SerSetBuf(BinRefNum, &inbuffB, serBlen)) print("\nERROR ! setting up serial buffer B\n");
print("<serial port B configed >\n");
}
end:
getoldA4();
}
sClose1 () {
getA4();
if (u == G->localuser) goto end; /* don't close if it's the local user */
if (u==0) RAMSDClose(sPortA);
if (u==1) RAMSDClose(sPortB);
print("C> <serial driver %d closed>\n",u);
end:
getoldA4();
}
sin1() /* Returns a character from serial port */
{
int keylen,result;
Byte check; /* used to check the CTS line */
char buffer[2]; /* a temp buffer for input storage */
CntrlParam contb; /* the blocks of bytes to do I/O */
IOParam iob;
getA4();
if (G->local[u]) {
if (keylen = strlen(G->keyboardbuf) > 0) { /* are there characters waiting ? */
G->input[u]=G->keyboardbuf[(keylen-1)];
G->keyboardbuf[(keylen-1)] = 0; /* shorten the string */
result=TRUE;
otheruser(FALSE); /* switch if it's time to switch */
goto end;
}
goto none;
}
if (u != G->localuser) {
/* some addresses for my info ($9FFFFA) or $50F04022 */
if (u == 0) {
if (G->carrdet[u] && (check = *(SCCRd + 2) & 0x20)) { /* CTS is bit 5, 1= carr loss */
print("C> CARRIER LOSS DETECTED DURING INPUT !!\n");
G->online[u]=FALSE;
goto none;
}
contb.ioRefNum = AinRefNum;
contb.csCode = 2; /* do a status to see if any chars */
if (PBStatus(&contb, FALSE)) goto none;
if (*(long *)&contb.csParam[0]) { /* do the check for characters */
iob.ioRefNum = AinRefNum;
iob.ioBuffer = (Ptr)buffer; /* characters waiting, get them */
iob.ioReqCount = 1;
if (PBRead(&iob, FALSE)) goto none;
if (G->nottransfer[u]) {G->input[u] = buffer[0] & 0x7F;} /* strip the 8th bit for text */
else G->input[u] = buffer[0]; /* G->input[u] is a global variable */
otheruser(FALSE); /* once and a while switch */
result=TRUE;
goto end;
}
goto none;
}
if (u == 1) {
if (G->carrdet[u] && (check = *(SCCRd + 0) & 0x20)) { /* CTS is bit 5, 1= carr loss */
print("C> CARRIER LOSS DETECTED DURING INPUT !!\n");
G->online[u]=FALSE;
goto none;
}
contb.ioRefNum = BinRefNum;
contb.csCode = 2; /* do a SerGetBuf to see if any chars */
if (PBStatus(&contb, FALSE)) goto none;
if (*(long *)&contb.csParam[0]) { /* do the check for characters */
iob.ioRefNum = BinRefNum;
iob.ioBuffer = (Ptr)buffer; /* characters waiting, get them */
iob.ioReqCount = 1;
if (PBRead(&iob, FALSE)) goto none;
if (G->nottransfer[u]) {G->input[u] = buffer[0] & 0x7F;} /* strip the 8th bit for text */
else G->input[u] = buffer[0]; /* G->input[u] is a global variable */
otheruser(FALSE); /* once and a while switch */
result=TRUE;
goto end;
}
}
} /* close the "BIG" if */
none:
otheruser(TRUE); /* switch NOW, don't wait when we arn't doing anything */
result=FALSE; /* no characters waiting */
end:
getoldA4();
return result;
}
sout1(x) /* sends a character to serial port */
unsigned char x;
{
int result;
char buffer[2]; /* a temp buffer for input storage */
Byte check; /* used to check the CTS line */
IOParam iob;
getA4();
if (G->monitor[u]) {if (x != 0x0A) printout(x);} /* for monitoring */
iob.ioCompletion = 0L; /* set these up now */
iob.ioBuffer = (Ptr)buffer;
iob.ioReqCount = 1;
loop:
if ( u != G->localuser) {
if (u == 0) {
if ( !G->nocheck[u] ){
if (G->carrdet[u] && (check = *(SCCRd + 2) & 0x20)) { /* CTS is bit 5, 1= carr loss */
print("C> CARRIER LOSS DETECTED DURING ** OUTPUT ** !!\n");
G->cancel[u]=TRUE;
G->online[u]=FALSE;
goto none;
}
}
while(TRUE) {
if (check = *(SCCRd + 2) & 0x04) break; /* Tx Empty is bit 2, 1= empty */
otheruser(TRUE); /* switch now, we arn't doing nothin */
}
buffer[0]=x;
iob.ioRefNum = AoutRefNum;
PBWrite(&iob, TRUE); /* asynchronous */
otheruser(FALSE); /* make sure we switch once and a while */
result=TRUE;
goto end;
}
if (u == 1) {
if ( !G->nocheck[u] ){
if (G->carrdet[u] && (check = *(SCCRd + 0) & 0x20)) { /* CTS is bit 5, 1= carr loss */
print("C> CARRIER LOSS DETECTED DURING ** OUTPUT ** !!\n");
G->cancel[u]=TRUE;
G->online[u]=FALSE;
result=FALSE;
goto end;
}
}
while(TRUE) {
if (check = *(SCCRd + 0) & 0x04) break; /* Tx Empty is bit 2, 1= empty */
otheruser(TRUE); /* switch now, we arn't doing nothin */
}
buffer[0]=x;
iob.ioRefNum = BoutRefNum;
PBWrite(&iob, TRUE); /* asynchronous */
otheruser(FALSE); /* make sure we switch once and a while */
result=TRUE;
goto end;
}
}
otheruser(FALSE); /* if it's the local user, we did print, so it's OK */
result=TRUE;
goto end;
none:
otheruser(TRUE); /* switch now if we arn't doing anything */
result=FALSE;
end:
getoldA4();
return result;
}
sflush1 () /* reads all input data until none avail */
{
IOParam iob;
getA4();
if (G->local[u]) {
G->keyboardbuf[0]=0; /* reset keyboard buffer */
G->input[u]=0;
goto end;
}
if (u == G->localuser || u > 1) goto end; /* don't do it if it's the local user */
if (u == 0) {
iob.ioRefNum = AinRefNum;
iob.ioCompletion = 0;
PBKillIO(&iob, FALSE);
G->input[u]=0; /* clear the old data */
}
if (u == 1) {
iob.ioRefNum = BinRefNum;
iob.ioCompletion = 0;
PBKillIO(&iob, FALSE);
G->input[u]=0; /* clear the old data */
}
end:
otheruser(FALSE);
getoldA4();
}
out1(x)
unsigned char x;
{
Byte i;
int a,c,result;
getA4();
result=TRUE;
G->cancel[u]=FALSE;
if (G->nottransfer[u]){
if ( !G->nocheck[u] ){
if (sin1()){
if ((G->input[u] & 0x1F) == 0x13) { /* CTL S, S, 3 and s */
sflush1();
in1(); /* wait for another keypress, if none, continue anyway */
sflush1();
}
else {
if ((G->input[u] & 0x1F) == 0x03) { /* ctl C, C, # and c */
sflush1();
G->cancel[u]=TRUE; /* return showing that we have been canceled */
}
}
}
if (x == 0x0A) { /* look for the LF after a CR */
if (G->userlines[u] && !G->cont[u]) { /* if it's not 0 */
if (++G->linecnt[u] >= G->userlines[u]){
sout1(x); /* do the LF now */
c = G->input[u]; /* save the old input value */
G->linecnt[u] = 1; /* reset the line count */
cmd1noecho("Cancel, No (pause):"); /* NO ECHO HERE !! */
i = G->input[u];
if (i == 'C' || i == 'c') {G->cancel[u]=TRUE;} /* cancel the output */
if (i == 'N' || i == 'n') {G->cont[u]=TRUE;}
a=0;
while (a++ < 19) {
sout1('\b');
sout1(' ');
sout1('\b');
} /* get rid of line */
G->input[u] = c; /* return the old input value */
G->linecnt[u] = 1; /* reset the line count */
goto end; /* skip the output */
}
}
}
}
}
result=sout1(x);
end:
getoldA4();
return result;
}
in1() /* returns true if a character is waiting, false for timeout */
{
long int time1;
int warn,result;
Byte check; /* used to check the CTS line */
getA4();
time1=Time;
warn=0;
if (G->local[u]) showline(); /* show the whole line line now, on the mac screen */
inloop: /* it will return like a time out if carrier is lost */
if ( ! sin1()) { /* if it's zero (no character) then */
if(!G->online[u]) {
result=FALSE;
goto end;
}
if (G->chatmode[u] > 0) { /* are we being chatted ??
if(!module(2,"chat",0L) G->chatmode[u]=0; /* call the chat module */
time1=Time; /* RESET the clock !! */
}
if ((Time-time1)<G->maxtime[u] ) goto inloop;
warn++;
time1=Time;
if (warn == 1) send("]Warning #1 inactivity timeout in %d seconds..]",(G->maxtime[u]*2));
if (warn == 2) send("]WARNING #2 INACTIVITY TIMEOUT IN %d SECONDS !!]",G->maxtime[u]);
if (warn == 3) {
send("]** INACTIVITY TIMEOUT, AUTO LOG OUT IN PROGRESS **]");
G->online[u]=FALSE;
result=FALSE;
goto end;
}
goto inloop;
};
result=TRUE;
end:
getoldA4();
return result;
}
setpointers(){ /* that's all this does ! */
G->seropen = sOpen1;
G->serclose = sClose1;
G->serin = sin1;
G->serout = sout1;
G->serflush = sflush1;
G->in = in1;
G->out = out1;
/* block serial in / out will go here when implimented */
}